package mk.com.ldm.corepoint.administration.client.presenter;

import java.util.ArrayList;
import java.util.Iterator;

import mk.com.ldm.corepoint.administration.client.CoreServiceAsync;
import mk.com.ldm.corepoint.administration.client.event.ModalEvent;
import mk.com.ldm.corepoint.administration.client.event.ModalEventHandler;
import mk.com.ldm.corepoint.administration.client.lib.CustomPagingScrollTable.CustomPagingScrollTable;
import mk.com.ldm.corepoint.administration.client.lib.CustomPagingScrollTable.PageChangedEvent;
import mk.com.ldm.corepoint.administration.client.lib.CustomPagingScrollTable.PageChangedEventHandler;
import mk.com.ldm.corepoint.administration.shared.LoginData;
import mk.com.ldm.corepoint.administration.shared.TemporaryStorage;
import mk.com.ldm.corepoint.administration.shared.UserObject;

import org.gwt.mosaic.ui.client.MessageBox;
import org.gwt.mosaic.ui.client.PopupMenu;
import org.gwt.mosaic.ui.client.ToolButton;
import org.gwt.mosaic.ui.client.layout.LayoutPanel;
import org.gwt.mosaic.ui.client.table.DefaultColumnDefinition;
import org.gwt.mosaic.ui.client.table.DefaultTableDefinition;
import org.gwt.mosaic.ui.client.table.FixedWidthFlexTable;
import org.gwt.mosaic.ui.client.table.FixedWidthGrid;
import org.gwt.mosaic.ui.client.table.IterableTableModel;
import org.gwt.mosaic.ui.client.table.PagingScrollTable;
import org.gwt.mosaic.ui.client.table.ScrollTable;
import org.gwt.mosaic.ui.client.table.TableModel;
import org.gwt.mosaic.ui.client.table.TableModelHelper.Request;
import org.gwt.mosaic.ui.client.table.TableModelHelper.Response;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.ScrollEvent;
import com.google.gwt.event.dom.client.ScrollHandler;
import com.google.gwt.event.shared.HandlerManager;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.Cookies;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Widget;

public class MainPresenter implements Presenter {
	public interface Display {
		Label getLoggedIn();
		Button getLogout();
		LayoutPanel getList();
		ArrayList<Widget> getSidebar();
		PopupMenu getListMenu();
		PopupMenu getListLangMenu();
		Widget asWidget();
		FixedWidthGrid getDataTable();
		FixedWidthFlexTable getHeaderTable();
		CustomPagingScrollTable getTable();
	}
	  
	  private final CoreServiceAsync rpcService;
	  private final HandlerManager eventBus;
	  private final Display display;
	  private ScrollTable liveTable = null;
	  
	  public MainPresenter(CoreServiceAsync rpcService, HandlerManager eventBus, Display view) {
	    this.rpcService = rpcService;
	    this.eventBus = eventBus;
	    this.display = view;
	  }
	  
	  public void bind() {
		  display.getLogout().addClickHandler(new ClickHandler(){

			@Override
			public void onClick(ClickEvent event) {
				doLogout();
			}
			  
		  });
		  
		  final Button listPages = (Button)display.getSidebar().get(5);
		  listPages.setEnabled(false);
		  listPages.addClickHandler(new ClickHandler(){

			@Override
			public void onClick(ClickEvent event) {
				display.getList().setStyleName("hide");
				MessageBox.info("Alert","Page list");
				display.getList().setStyleName("show");
			}
			  
		  });
		  
		  
		   
		  final Button listUsers = (Button)display.getSidebar().get(8);
		  listUsers.setEnabled(false);
		  listUsers.addClickHandler(new ClickHandler(){

			@Override
			public void onClick(ClickEvent event) {
				display.getList().setStyleName("hide");
				
				FixedWidthFlexTable headerTable = display.getHeaderTable();
				headerTable.setHTML(0, 0, "Username");
				headerTable.setHTML(0, 1, "Password");
				
				final FixedWidthGrid dataTable = display.getDataTable();
				
				rpcService.getUsers(new AsyncCallback<ArrayList<UserObject>>() {
					
					@Override
					public void onSuccess(final ArrayList<UserObject> result) {
						dataTable.resize(result.size(), 2);
						for(int i=0;i<result.size();i++){
							dataTable.setText(i, 0, result.get(i).getUsername());
							dataTable.setText(i, 1, result.get(i).getPassword());
						}
						display.getTable().addPageChangedEventHandler(new PageChangedEventHandler() {
							@Override
							public void onPageChanged(PageChangedEvent event) {
								MessageBox.alert("Event", "Event sent<br />Current page is: "+event.getCurrentPage()+
										"<br />Reccords per page: "+event.getPageSize());
							}
						});
						display.getTable().redraw();
						
						//display.setTable(headerTable);
					}
					
					@Override
					public void onFailure(Throwable caught) {
						MessageBox.alert("FAIL", "Could not get the list");
					}
				});
				//MessageBox.info("Alert","User list");
				display.getList().setStyleName("show");
			}
			  
		  });
		  
		  final Button newProject = (Button)display.getSidebar().get(1);
		  newProject.addClickHandler(new ClickHandler(){

			@Override
			public void onClick(ClickEvent event) {
				eventBus.fireEvent(new ModalEvent("new","project"));
			}
			  
		  });
		  
		  final Button newPage = (Button)display.getSidebar().get(4);
		  newPage.setEnabled(false);
		  newPage.addClickHandler(new ClickHandler(){

			@Override
			public void onClick(ClickEvent event) {
				eventBus.fireEvent(new ModalEvent("new","name"));
			}
			  
		  });
		  
		  final Button newUser = (Button)display.getSidebar().get(7);
		  newUser.setEnabled(false);
		  newUser.addClickHandler(new ClickHandler(){

			@Override
			public void onClick(ClickEvent event) {
				eventBus.fireEvent(new ModalEvent("new","user"));
			}
			  
		  });
		  
		  final Button newLanguage = (Button)display.getSidebar().get(10);
		  newLanguage.setEnabled(false);
		  newLanguage.addClickHandler(new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent event) {
				eventBus.fireEvent(new ModalEvent("new","language"));
			}
		});
		  
		  final ToolButton selectLanguage = (ToolButton)display.getSidebar().get(11);
		  selectLanguage.setEnabled(false);
		  
		  final Button appSettings = (Button)display.getSidebar().get(13);
		  appSettings.setEnabled(false);
		  appSettings.addClickHandler(new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent event) {
				eventBus.fireEvent(new ModalEvent("edit", "application settings"));
			}
		});
		  
		  final ToolButton openProject = (ToolButton)display.getSidebar().get(2);
		  openProject.addClickHandler(new ClickHandler(){

			@Override
			public void onClick(ClickEvent event) {
				if(openProject.getText().equals("Select project...")){
					MessageBox.alert("Warning","You must select a project before opening. Please select a project.");
				} else {
					String info = openProject.getText().substring(5, openProject.getText().length());
					selectProject(info);
					listPages.setEnabled(true);
					listUsers.setEnabled(true);
					newPage.setEnabled(true);
					newUser.setEnabled(true);
					newLanguage.setEnabled(true);
					selectLanguage.setEnabled(true);
					appSettings.setEnabled(true);
					TemporaryStorage.getInstance().setSelectedProject(info);
					MessageBox.info("Project"+info, "Project "+info+" opened.");
				}
				
			}
			  
		  });
	  }
	  
	  public void go(final HasWidgets container) {
	    bind();
	    container.clear();
	    if(LoginData.getInstance().getUsername() == null || LoginData.getInstance().getHash() == null){
	    	History.newItem("login");
	    } else if(LoginData.getInstance().getUsername().equals(Cookies.getCookie("username")) && LoginData.getInstance().getHash().equals(Cookies.getCookie("hash"))) {
	    	
	    	display.getLoggedIn().setText("Logged in as: "+LoginData.getInstance().getUsername());
	    	getProjects();
	    	container.add(display.asWidget());
	    }
	   
	  }
	  
	  public void doLogout(){
		  LoginData.getInstance().setUsername(null);
		  LoginData.getInstance().setHash(null);
		  Cookies.removeCookie("username");
		  Cookies.removeCookie("hash");
		  History.newItem("login");
	  }
	  
	
	  public void getProjects(){
		  rpcService.getProjects(new AsyncCallback<ArrayList<String>>(){

			@Override
			public void onFailure(Throwable caught) {
				MessageBox.error("Server", "Failed to communicate with the server");
			}

			@Override
			public void onSuccess(ArrayList<String> result) {
				PopupMenu lb = display.getListMenu();
				
				for(final String r:result){
					lb.addItem(r, new Command(){
						@Override
						public void execute() {
							ToolButton tb = (ToolButton)display.getSidebar().get(2);
							tb.setText(" Open "+r);
						}});
				}
			}
			  
		  });
	  }
	  
	  public void selectProject(String name){
		  rpcService.selectProject(name, new AsyncCallback<String>(){

			@Override
			public void onFailure(Throwable caught) {
				MessageBox.error("Server", "Failed to communicate with the server");
			}

			@Override
			public void onSuccess(String result) {
			}
			  
		  });
	  }
	  
}
